Exiled by Fate: The Growing Refugee Crisis

AUTHOR
Harsh Shinde

A Report on Global Refugee Crisis.

Across continents, millions of people are forced to make an impossible choice-stay and risk their lives or flee into the unknown.
War, persecution, economic collapse, and climate disasters have fueled an unprecedented surge in global displacement.

The scale of displacement is staggering, yet behind every statistic lies a personal tragedy-a family torn apart, a home left in ruins, a future rewritten.
The crisis isn’t just about movement; it’s about survival.

Code
import pandas as pd
import plotly.express as px
from IPython.display import HTML


df = pd.read_csv('unicef_Indicator_1_Cleaned_1.csv')
mdf = pd.read_csv('meta data (cleaned 1).csv')
df = df.rename(columns={'Country': 'country', 'Year': 'year'})
df = pd.merge(df, mdf[['country','year','Population, total']], on=['country','year'], how='left')
df['total_refugees'] = (df['obs_value'] / 1000) * df['Population, total']
grouped = df.groupby('year', as_index=False).agg(total_refugees=('total_refugees','sum'))

# creating the chart
fig = px.bar(
    grouped,
    x='year',
    y='total_refugees',
    labels={'year':'Year','total_refugees':'Total Refugee Count'},
    color='total_refugees',
    color_continuous_scale=['#fee5d9','#fcae91','#fb6a4a','#de2d26','#a50f15'],
    title='Global Refugee Trends Over Time',
    hover_data={'total_refugees':':.0f'}
)

#  Styling the bars
fig.update_traces(
    marker_line_color='black',
    marker_line_width=1
)

#  Axes marks changing the style
fig.update_yaxes(
    title_text='Total Refugee Count',
    tickformat='.1s',       
    dtick=1e7,               
    range=[0,4e7]          
)

#  Colorbar style change and markers positioning changed
fig.update_layout(
    plot_bgcolor='#f8ebd8',
    paper_bgcolor='#f8ebd8',
    font=dict(family='Arial', size=12, color='black'),
    title_font_size=20,
    title_x=0.5,
    margin=dict(l=60,r=60,t=80,b=60),

    coloraxis_colorbar=dict(
        title='Total Refugee Count',
        orientation='h',
        tickmode='array',
        tickvals=[0,1e7,2e7,3e7,4e7],
        ticktext=['0M','10M','20M','30M','40M'],
        thickness=20,
        outlinecolor='black',
        outlinewidth=2,
        ticks='outside',
        ticklen=5,
        tickcolor='black',
        bgcolor='#f8ebd8',
        x=0.5, xanchor='center', y=-0.3, yanchor='top'
    )
)

#  Customizing the X-axis style 
fig.update_xaxes(
    title_text='Year',
    tickmode='linear',
    dtick=1,
    showgrid=False,
    zeroline=False
)

# Displaying the output of the code
HTML(fig.to_html())

Who Bears The Weight of Displacement?

This chart highlights the top 15 countries that have hosted the most refugees over the years. What stands out is the overwhelming contribution of nations like Pakistan, Turkey, and Iran, who have shouldered a significant portion of the global refugee population. These countries, often not the wealthiest, show a remarkable level of humanitarian commitment.

While the refugee crisis is global, its burden is not equally shared. Nations with the fewest resources often bear the heaviest responsibility, hosting millions despite economic hardship. Meanwhile, wealthier countries-equipped with the means to help-remain on the sidelines. The numbers reveal a stark reality: humanitarian duty is not dictated by wealth, but by proximity and policy. Some nations have seen their refugee populations swell to make up a significant percentage of their total inhabitants, reshaping demographics, economies, and social structures. Others, despite their stability, take in only a fraction of those in need. This is not just a test of borders-it is a test of global responsibility.

Code
import pandas as pd
import plotly.express as px
from IPython.display import HTML

# Loading and preparing the data
df = pd.read_csv('unicef_Indicator_1_Cleaned_1.csv')
mdf = pd.read_csv('meta data (cleaned 1).csv')

# Merging the two data
df = df.rename(columns={'Country': 'country', 'Year': 'year'})
df = pd.merge(df, mdf[['country', 'year', 'Population, total']], on=['country', 'year'], how='left')

# Calculating the total refugees count
df['total_refugees'] = (df['obs_value'] / 1000) * df['Population, total']

# Aggregating the  total refugee count by country and sorting by descending
top_countries = df.groupby('country')['total_refugees'].sum().reset_index()
top_countries = top_countries.sort_values(by='total_refugees', ascending=False).head(15)

# Creating the bar chart
fig2 = px.bar(
    top_countries,
    x='total_refugees',
    y='country',
    orientation='h',
    title='Who Opens Their Doors?',
    labels={'country': 'Country', 'total_refugees': 'Total Refugee Count'},
    color='total_refugees',
    color_continuous_scale='OrRd',
    hover_data={'total_refugees': ':.0f'},
    category_orders={"country": top_countries['country'].tolist()}  
)

# Adding the borders and updating the layout
fig2.update_traces(
    marker_line_color='black',
    marker_line_width=1
)

fig2.update_layout(
    paper_bgcolor='#f8ebd8',  
    plot_bgcolor='#f8ebd8',  
    margin=dict(l=20, r=20, t=40, b=40),  
    xaxis_title='Total Refugee Count',
    yaxis_title='Country',
    coloraxis_showscale=False,
    font=dict(color='black'),
    title=dict(
        text='Who Opens Their Doors?',
        x=0.5,  # Center the title
        xanchor='center'
    )
)

HTML(fig2.to_html())

Nowhere to Call Home

For millions, displacement is not just a statistic-it’s a struggle for survival. Families are torn apart, children grow up in limbo, and entire communities are forced to rebuild from nothing. While policies and economics shape refugee movement, the real question is how the world chooses to respond. Will refugees be seen as a burden, or as individuals with the potential to rebuild and thrive? The answer will define the future of displacement.

Code
import pandas as pd
import plotly.express as px
from IPython.display import HTML
import pycountry

df = pd.read_csv('unicef_Indicator_1_Cleaned_1.csv')
mdf = pd.read_csv('meta data (cleaned 1).csv')
df = df.rename(columns={'Country':'country','Year':'year'})
df = pd.merge(df, mdf[['country','year','Population, total']],
              on=['country','year'], how='left')
df['total_refugees'] = (df['obs_value']/1000) * df['Population, total']
choropleth_data = df.groupby('country', as_index=False)['total_refugees'].sum()


def get_iso3(name):
    try:   return pycountry.countries.lookup(name).alpha_3
    except: return None
choropleth_data['iso_alpha'] = choropleth_data['country'].apply(get_iso3)
choropleth_data.dropna(subset=['iso_alpha'], inplace=True)

# Creating the map
fig3 = px.choropleth(
    choropleth_data,
    locations='iso_alpha',
    color='total_refugees',
    hover_name='country',
    hover_data={'total_refugees':':.0f','iso_alpha':False},
    color_continuous_scale='Oranges',
    title='Mapping the Global Refugee Footprint',
    labels={'total_refugees':'Total Refugee Count'},
    projection='mercator'
)

# changing the  layout to remove scroll, and fill the space
fig3.update_geos(
    fitbounds="locations",
    visible=False,      
    showcountries=True,
    countrycolor="black",
    showland=True,
    landcolor="#f8ebd8",
    showocean=True,
    oceancolor="lightblue"
)
fig3.update_layout(
    autosize=True,
    height=500,          
    width=800,           
    margin=dict(l=20, r=20, t=50, b=20),
    paper_bgcolor="#f8ebd8",
    plot_bgcolor="#f8ebd8",
    coloraxis_colorbar=dict(
        title="Total Refugees",
        tickformat=",.0s",
        thickness=15,
        outlinecolor="black",
        outlinewidth=1
    )
)


html = fig3.to_html(full_html=False, config={'responsive':True})
HTML(html)

Wealth, Will, and Welcome

The relationship between GDP and refugee intake exposes deep inequalities. While economic powerhouses have the capacity to accommodate, they often don’t. Instead, those on the frontlines-often struggling themselves-become the world’s largest refugee hosts. The question isn’t just about who can take them in, but who chooses to. A troubling trend emerges: as global GDP rises, so do restrictive asylum policies. Nations with the means to help build walls instead of bridges, pushing responsibility onto their less affluent neighbors. Meanwhile, displacement continues to grow, leaving millions trapped in limbo.

Code
from plotnine import (
    ggplot, aes, geom_point, geom_smooth,
    scale_color_gradient, labs, theme_minimal,
    theme, element_rect, element_text
)

(
    ggplot(df_plot, aes(x="total_refugees", y="gdp_per_capita"))
    # 1) Adding the Big black circles for the border effect
    + geom_point(
        size=4.5,
        color="black",
        alpha=1
    )
    # 2) small colour circle to show the data
    + geom_point(
        aes(color="total_refugees"),
        size=4.5,
        alpha=0.8
    )
    # 3) Adding a Regression line in the chart
    + geom_smooth(
        method="lm", se=False,
        color="#a50f15", linetype="--", size=1.2
    )
    # 4) making the Reds gradient colour scale
    + scale_color_gradient(
        low="#fee5d9", high="#a50f15",
        name="Total Refugees"
    )
    + labs(
        title="Wealth and Welcome: Do They Correlate?",
        x="Total Refugee Count",
        y="GDP per Capita (constant 2015 US$)"
    )
    + theme_minimal()
    + theme(
        plot_background=element_rect(fill="#f8ebd8", color=None),
        panel_background=element_rect(fill="#f8ebd8", color=None),
        legend_background=element_rect(fill="#f8ebd8", color=None),
        legend_position="right",
        plot_title=element_text(size=16, weight="bold"),
        axis_title=element_text(size=12),
        legend_title=element_text(size=11),
        legend_text=element_text(size=9)
    )
)

PEO Logo

Donate Logo

UNICEF Logo